using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Globalization;

namespace Atechnology.glassCAD.Shapes.CutViewer
{
    enum AnzHeader
    {
        Start,
        Size,
        Line, 
        Arc,
        Coordinates,
        End
    }

    public class AnzParser : IParser
    {
        public CutModel Parse(string filePath)
        {
            Stream str = File.Open(filePath, FileMode.Open);
            CutModel result = this.Parse(str);
            str.Close();
            return result;
        }

        public CutModel Parse(Stream str)
        {
            AnzCutModel result = new AnzCutModel();
            StreamReader reader = new StreamReader(str);
            List<Line> sizeLines = this.ParseSize(reader);
            int geometryCounter = 0;
            result.AnzSize = new System.Drawing.SizeF(sizeLines[0].BoundingBox.Size.Width, sizeLines[1].BoundingBox.Size.Height);

            foreach (Line line in sizeLines)
            {
                line.Tip.Text = geometryCounter.ToString();
                line.Update();
                result.Figures.Add(line);
                geometryCounter++;
            }

            AnzHeader header = this.ReadHeader(reader);
            IGeometry geometry;
            
            while (header != AnzHeader.End)
            {
                switch (header)
                {
                    case AnzHeader.Line:
                        geometry = this.ReadLine(reader);
                        geometry.Tip.Text = geometryCounter.ToString();
                        geometry.Update();
                        result.Figures.Add(geometry);
                        geometryCounter++;
                        break;
                    case AnzHeader.Arc:
                        geometry = this.ReadArc(reader);
                        geometry.Tip.Text = geometryCounter.ToString();
                        geometry.Update();
                        result.Figures.Add(geometry);
                        geometryCounter++;
                        break;
                }
                header = this.ReadHeader(reader);
            }
            reader.Close();
            return result;
        }

        private List<Line> ParseSize(StreamReader reader)
        {
            List<Line> lines = new List<Line>(); 
            string sizeString = reader.ReadLine();
            string width = sizeString.Split(' ')[0];
            string height = sizeString.Split(' ')[1];
            Line line = new Line();
            line.Points[0].X = 0;
            line.Points[0].Y = 0;
            line.Points[1].X = float.Parse(width, new CultureInfo("en-US"));
            line.Points[1].Y = 0;
            lines.Add(line);
            line = new Line();
            line.Points[0].X = float.Parse(width, new CultureInfo("en-US"));
            line.Points[0].Y = 0;
            line.Points[1].X = float.Parse(width, new CultureInfo("en-US"));
            line.Points[1].Y = float.Parse(height, new CultureInfo("en-US"));
            lines.Add(line);
            line = new Line();
            line.Points[0].X = float.Parse(width, new CultureInfo("en-US"));
            line.Points[0].Y = float.Parse(height, new CultureInfo("en-US"));
            line.Points[1].X = 0;
            line.Points[1].Y = float.Parse(height, new CultureInfo("en-US"));
            lines.Add(line);
            line = new Line();
            line.Points[0].X = 0;
            line.Points[0].Y = float.Parse(height, new CultureInfo("en-US"));
            line.Points[1].X = 0;
            line.Points[1].Y = 0;
            lines.Add(line);
            return lines;
        }

        //private AnzHeader FindHeader(StreamReader reader)
        //{
        //    AnzHeader header = AnzHeader.Start;

        //    while(header != AnzHeader.Arc || header != AnzHeader.Line || header != AnzHeader.End)
        //        header = AnzParser.ReadHeader(reader);

        //    return header;
        //}

        private AnzHeader ReadHeader(StreamReader reader)
        {
            string line = reader.ReadLine();
            if (line == null)
                return AnzHeader.End;

            switch (line)
            {
                case "1 0 0 2":
                    return AnzHeader.Size;
                case "2 0 0 2":
                    return AnzHeader.Line;
                case "3 0 0 2":
                    return AnzHeader.Arc;
                case "7 0 0 7":
                    return AnzHeader.End;
                default:
                    if (line.Contains("2 10") && line.Contains("1"))
                        return AnzHeader.Line;
                    if (line.Contains("2 10") && line.Contains("3"))
                        return AnzHeader.Arc;

                    return AnzHeader.Coordinates;
            }
        }

        private Line ReadLine(StreamReader reader)
        {
            Line line = new Line();
            string startX = reader.ReadLine();
            string startY = reader.ReadLine();
            string endX = reader.ReadLine();
            string endY = reader.ReadLine();
            line.Points[0].X = float.Parse(startX, new CultureInfo("en-US"));
            line.Points[0].Y = float.Parse(startY, new CultureInfo("en-US"));
            line.Points[1].X = float.Parse(endX, new CultureInfo("en-US"));
            line.Points[1].Y = float.Parse(endY, new CultureInfo("en-US"));
            return line;
        }

        private Arc ReadArc(StreamReader reader)
        {
            Arc arc = new Arc();
            float x = float.Parse(reader.ReadLine(), new CultureInfo("en-US"));
            float y = float.Parse(reader.ReadLine(), new CultureInfo("en-US"));
            arc.Center = new System.Drawing.PointF(x, y); 
            arc.Radius = float.Parse(reader.ReadLine(), new CultureInfo("en-US"));
            arc.StartAngle = float.Parse(reader.ReadLine(), new CultureInfo("en-US"));
            arc.EndAngle = float.Parse(reader.ReadLine(), new CultureInfo("en-US"));
            reader.ReadLine();
            reader.ReadLine();
            reader.ReadLine();
            reader.ReadLine();
            return arc;
        }
            
    }
}
